/*******************************************************************************
 * Copyright (c) 2002 IBM Corporation and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Common Public License v0.5 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: IBM - Initial API and implementation Boris Pruessmann -
 * Cleanup, documentation
 ******************************************************************************/
package net.sourceforge.perforce.ui;

import com.google.common.collect.Maps;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;

import java.util.Map;

/**
 * Maintains a cache of OverlayIcons.
 * 
 * @version $Revision: 488 $
 * @author IBM
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class OverlayIconCache {
  //----------------------------------------------------------------------------
  // Public Constants

  /** ImageDescriptor: Out Of Date. */
  public static final ImageDescriptor OUT_OF_DATE =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OUTOFDATE));

  /** Location of the Out of Date decoration. */
  public static final int OUT_OF_DATE_LOCATION = OverlayIcon.BOTTOM_RIGHT;

  /** ImageDescriptor: has Remote. */
  public static final ImageDescriptor HAS_REMOTE =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_HASREMOTE));

  /** Location of the 'has remote' decoration. */
  public static final int HAS_REMOTE_LOCATION = OverlayIcon.BOTTOM_RIGHT;

  /** ImageDescriptor: no Remote. */
  public static final ImageDescriptor NO_REMOTE =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_NO_REMOTE));

  /** Location of the 'no remote' decoration. */
  public static final int NO_REMOTE_LOCATION = OverlayIcon.BOTTOM_RIGHT;

  /** ImageDescriptor: Open For Add. */
  public static final ImageDescriptor OPEN_FOR_ADD =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OPENFORADD));

  /** Location of the 'open for add' decoration. */
  public static final int OPEN_FOR_ADD_LOCATION = OverlayIcon.TOP_LEFT;

  /** ImageDescriptor: Open For Edit. */
  public static final ImageDescriptor OPEN_FOR_EDIT =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OPENFOREDIT));

  /** Location of the 'open for edit' decoration. */
  public static final int OPEN_FOR_EDIT_LOCATION = OverlayIcon.TOP_LEFT;

  /** ImageDescriptor: Open For Delete. */
  public static final ImageDescriptor OPEN_FOR_DELETE =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OPENFORDELETE));

  /** Location of the 'open for delete' decoration. */
  public static final int OPEN_FOR_DELETE_LOCATION = OverlayIcon.TOP_LEFT;

  /** ImageDescriptor: Other Open For Add. */
  public static final ImageDescriptor OTHER_OPEN_FOR_ADD =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OTHER_OPENFORADD));

  /** Location of the 'other open for add' decoration. */
  public static final int OTHER_OPEN_FOR_ADD_LOCATION = OverlayIcon.TOP_RIGHT;

  /** ImageDescriptor: Other Open For Edit. */
  public static final ImageDescriptor OTHER_OPEN_FOR_EDIT =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OTHER_OPENFOREDIT));

  /** Location of the 'other open for edit' decoration. */
  public static final int OTHER_OPEN_FOR_EDIT_LOCATION = OverlayIcon.TOP_RIGHT;

  /** ImageDescriptor: Other Open For Delete. */
  public static final ImageDescriptor OTHER_OPEN_FOR_DELETE =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_OTHER_OPENFORDELETE));

  /** Location of the 'other open for delete' decoration. */
  public static final int OTHER_OPEN_FOR_DELETE_LOCATION = OverlayIcon.TOP_RIGHT;

  /** Image Descriptor: Locked by us */
  public static final ImageDescriptor OUR_LOCK =
      new CachedImageDescriptor(PerforceUIPlugin.getPlugin().getImageDescriptor(
          PerforceUIPlugin.OVR_LOCKED));

  /** Location of the 'locked by us' decoration. */
  public static final int OUR_LOCK_LOCATION = OverlayIcon.BOTTOM_LEFT;

  // ---------------------------------------------------------------------------
  // Private Variables

  /** Map that contains the cached data. */
  private Map<OverlayIcon, Image> cache = Maps.newHashMap();

  //----------------------------------------------------------------------------
  // -- Public Methods

  /**
   * Returns the Image for the given icon. First, tries to locate in the cache.
   * 
   * @param icon the icon.
   * @return the image.
   */
  public Image getImageFor(OverlayIcon icon) {
    Image image = cache.get(icon);
    if (image == null) {
      image = icon.createImage();
      cache.put(icon, image);
    }

    return image;
  }

  /** Disposes of all images in the cache. */
  public void disposeAll() {
    for (Image image : cache.values()) {
      image.dispose();
    }
    cache.clear();
  }

  // ----------------------------------------------------------------------
  // Private Nested Classes

  /** Define a cached image descriptor which only creates the image data once */
  private static class CachedImageDescriptor extends ImageDescriptor {
    // -----------------------------------------------------------------------
    // Private Variables

    /** Stores the ImageDescriptor. */
    private ImageDescriptor descriptor;
    /** Stores the ImageData. */
    private ImageData data;

    // ---------------------------------------------------------------------
    // Public Constructors

    /**
     * Constructor for CachedImageDescriptor.
     * 
     * @param descriptor the image descriptor.
     */
    public CachedImageDescriptor(ImageDescriptor descriptor) {
      this.descriptor = descriptor;
    }

    //--------------------------------------------------------------------------
    // Public Methods

    /**
     * Called to retrieve the object's ImageData.
     * 
     * @return the ImageData.
     */
    @Override
    public ImageData getImageData() {
      if (data == null) {
        data = descriptor.getImageData();
      }

      return data;
    }
  }
}
